﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace DataGridViewVirtualCombo
{
	static class Program
	{
		private class ValueDto
		{
			public int Value { get; private set; }

			public string StringValue
			{
				get { return string.Format("2^{0}", Value); }
			}

			public ValueDto(int value)
			{
				Value = value;
			}
		}

		private static readonly List<ValueDto> values = new List<ValueDto>();
		private static readonly int[] valuesStore = new int[2];

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main()
		{
			Application.EnableVisualStyles();
			Application.SetCompatibleTextRenderingDefault(false);

			FillValues();

			var form = new Form();
			var dataGridView = new DataGridView
			                   {
			                   	Dock = DockStyle.Fill,
			                   	VirtualMode = true,
			                   	RowCount = 5,
			                   	ColumnCount = 2,
			                   	AllowUserToAddRows = false,
			                   	AllowUserToDeleteRows = false,
			                   	EditMode = DataGridViewEditMode.EditOnEnter
			                   };
			dataGridView.CellBeginEdit += DataGridView_CellBeginEdit;
			dataGridView.CellValueNeeded += DataGridView_CellValueNeeded;
			dataGridView.CellValuePushed += DataGridView_CellValuePushed;

			var comboBoxCell0 = new DataGridViewComboBoxCell
			                    {DataSource = values, ValueMember = "Value", DisplayMember = "StringValue"};
			dataGridView.Rows[0].Cells[0] = comboBoxCell0;
			var comboBoxCell1 = new DataGridViewComboBoxCell
			                    {DataSource = values, ValueMember = "Value", DisplayMember = "StringValue"};
			dataGridView.Rows[0].Cells[1] = comboBoxCell1;

			form.Controls.Add(dataGridView);

			Application.Run(form);
		}

		private static void DataGridView_CellBeginEdit(object sender, DataGridViewCellCancelEventArgs e)
		{
			if (e.RowIndex != 0)
			{
				e.Cancel = true;
			}
		}

		private static void DataGridView_CellValueNeeded(object sender, DataGridViewCellValueEventArgs e)
		{
			if (e.RowIndex == 0)
			{
				e.Value = valuesStore[e.ColumnIndex];
			}
			else
			{
				e.Value = string.Format("({0}; {1})", e.RowIndex, e.ColumnIndex);
			}
		}

		private static void DataGridView_CellValuePushed(object sender, DataGridViewCellValueEventArgs e)
		{
			if (e.RowIndex != 0)
			{
				return;
			}

			valuesStore[e.ColumnIndex] = (int)e.Value;
		}

		private static void FillValues()
		{
			for (var i = -2; i <= 2; i++)
			{
				values.Add(new ValueDto(i));
			}

			var middle = values.Count/2;
			valuesStore[0] = values[middle].Value;
			valuesStore[1] = values[middle].Value;
		}
	}
}
